<template>
  <div ref="chart" :style="{ width: width, height: height }"></div>
</template>

<script>
import * as echarts from "echarts";

export default {
  name: "DraggableLineChart",
  props: {
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "500px",
    },
    initialData: {
      type: Array,
      default: () => Array.from({ length: 10 }, (_, i) => [i + 1, 10]),
    },
    yMin: {
      type: Number,
      default: 0,
    },
    yMax: {
      type: Number,
      default: 30,
    },
  },
  data() {
    return {
      chart: null,
      symbolSize: 16,
      data: [],
    };
  },
  watch: {
    initialData: {
      handler(newVal) {
        this.data = [...newVal];
        this.initChart();
      },
      deep: true,
      immediate: true,
    },
  },
  mounted() {
    this.initChart();
    window.addEventListener("resize", this.handleResize);
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.handleResize);
    if (this.chart) {
      this.chart.dispose();
      this.chart = null;
    }
  },
  methods: {
    initChart() {
      if (this.chart) this.chart.dispose();

      this.chart = echarts.init(this.$refs.chart);
      this.setBaseOption();
      this.initDraggable();
      this.bindEvents();
    },

    setBaseOption() {
      const option = {
        title: {
          text: "可拖拽调整曲线",
          left: "center",
          textStyle: {
            color: "#333",
            fontSize: 16,
          },
        },
        tooltip: {
          triggerOn: "none",
          formatter: (params) => {
            return `第 ${params.data[0]} 天<br>数值: ${params.data[1].toFixed(
              2
            )}`;
          },
        },
        grid: {
          top: "15%",
          bottom: "15%",
        },
        xAxis: {
          min: 1,
          max: 10,
          interval: 1,
          type: "value",
          name: "天数",
          axisLine: {
            lineStyle: {
              color: "#666",
            },
          },
        },
        yAxis: {
          min: this.yMin,
          max: this.yMax,
          type: "value",
          name: "数值",
          axisLine: {
            lineStyle: {
              color: "#666",
            },
          },
        },
        series: [
          {
            id: "mainSeries",
            type: "line",
            smooth: false,
            symbolSize: this.symbolSize,
            itemStyle: {
              color: "#5470c6",
              borderColor: "#fff",
              borderWidth: 2,
            },
            emphasis: {
              itemStyle: {
                color: "#ff4500",
                borderWidth: 3,
                shadowBlur: 10,
                shadowColor: "rgba(0,0,0,0.3)",
              },
            },
            data: this.data,
          },
        ],
      };
      this.chart.setOption(option);
    },

    initDraggable() {
      this.$nextTick(() => {
        this.chart.setOption({
          graphic: this.data.map((item, index) => ({
            type: "circle",
            position: this.chart.convertToPixel("grid", item),
            shape: { cx: 0, cy: 0, r: this.symbolSize / 2 },
            invisible: true,
            draggable: true,
            ondrag: (e) => this.handleDrag(index, [e.x, e.y]),
            z: 100,
          })),
        });
      });
    },

    bindEvents() {
      this.chart.on("click", (params) => {
        if (params.componentType === "series") {
          this.handleClick(params.dataIndex);
        }
      });
    },

    handleDrag(index, pos) {
      const originalX = this.data[index][0];
      const coord = this.chart.convertFromPixel("grid", pos);
      const newY = Math.min(Math.max(coord[1], this.yMin), this.yMax);

      this.$set(this.data, index, [originalX, newY]);
      this.updateChart();
      this.$emit("update", this.data);
    },

    handleClick(index) {
      this.highlightPoint(index);
      this.$emit("point-click", {
        index,
        data: this.data[index],
      });
    },

    highlightPoint(index) {
      this.chart.dispatchAction({
        type: "highlight",
        seriesIndex: 0,
        dataIndex: index,
      });
      setTimeout(() => {
        this.chart.dispatchAction({
          type: "downplay",
          seriesIndex: 0,
          dataIndex: index,
        });
      }, 1500);
    },

    updateChart() {
      this.chart.setOption({
        series: [
          {
            data: this.data,
          },
        ],
      });
      this.updateDraggable();
    },

    updateDraggable() {
      this.chart.setOption({
        graphic: this.data.map((item) => ({
          position: this.chart.convertToPixel("grid", item),
        })),
      });
    },

    handleResize() {
      if (this.chart) {
        this.chart.resize();
        this.updateDraggable();
      }
    },
  },
};
</script>

<style scoped>
div {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}
</style>